﻿using System;
using biz.ritter.javapi.lang;
using Nofs.Net.Common.Interfaces.Domain;
using java = biz.ritter.javapi.lang;

namespace Nofs.Net.Domain.Impl
{

    public class MethodParameter : IMethodParameter
    {
        private String _parameter;
        private Class _type;
        private Object _value;
        private bool _hasValue = false;

        public MethodParameter(String value, String type, int index)// throws Exception 
        {
            _value = value;
            _type = GetType(type);
            //_parameter = "$" + index;
            _parameter = value;
        }

        public MethodParameter(String xml) //throws Exception
        {
            _hasValue = true;
            int firstQuote = xml.indexOf('\"', 0);
            if (firstQuote == (-1))
            {
                throw new System.Exception("invalid method invocation format");
            }
            int secondQuote = xml.indexOf('\"', firstQuote + 1);
            if (secondQuote == (-1))
            {
                throw new System.Exception("invalid method invocation format");
            }
            int thirdQuote = xml.indexOf('\"', secondQuote + 1);
            if (thirdQuote == (-1))
            {
                throw new System.Exception("invalid method invocation format");
            }
            int fourthQuote = xml.indexOf('\"', thirdQuote + 1);
            if (fourthQuote == (-1))
            {
                throw new System.Exception("invalid method invocation format");
            }
            _parameter = xml.substring(firstQuote + 1, secondQuote);
            String typeStr = xml.substring(thirdQuote + 1, fourthQuote);
            _type = GetType(typeStr);
        }

        private static Class GetType(String className) //throws Exception 
        {
            Class type;
            if ("Complex".compareTo(className) == 0)
            {
                type = null;
            }
            else if (typeof(long).Name.compareTo(className) == 0)
            {
                type = typeof(long).getClass();
            }
            else if (typeof(byte).Name.compareTo(className) == 0)
            {
                type = typeof(byte).getClass();
            }
            else if (typeof(short).Name.compareTo(className) == 0)
            {
                type = typeof(short).getClass();
            }
            else if (typeof(int).Name.compareTo(className) == 0)
            {
                type = typeof(int).getClass();
            }
            else if (typeof(float).Name.compareTo(className) == 0)
            {
                type = typeof(float).getClass();
            }
            else if (typeof(double).Name.compareTo(className) == 0)
            {
                type = typeof(double).getClass();
            }
            else if (typeof(bool).Name.compareTo(className) == 0)
            {
                type = typeof(bool).getClass();
            }
            else if (typeof(char).Name.compareTo(className) == 0)
            {
                type = typeof(char).getClass();
            }
            else if (typeof(String).Name.compareTo(className) == 0)
            {
                type = typeof(String).getClass();
            }
            else if (typeof(Long).Name.compareTo(className) == 0)
            {
                type = typeof(Long).getClass();
            }
            else if (typeof(java.Byte).Name.compareTo(className) == 0)
            {
                type = typeof(java.Byte).getClass();
            }
            else if (typeof(Short).Name.compareTo(className) == 0)
            {
                type = typeof(Short).getClass();
            }
            else if (typeof(Integer).Name.compareTo(className) == 0)
            {
                type = typeof(Integer).getClass();
            }
            else if (typeof(Float).Name.compareTo(className) == 0)
            {
                type = typeof(Float).getClass();
            }
            else if (typeof(java.Double).Name.compareTo(className) == 0)
            {
                type = typeof(java.Double).getClass();
            }
            else if (typeof(java.Boolean).Name.compareTo(className) == 0)
            {
                type = typeof(java.Boolean).getClass();
            }
            else if (typeof(Character).Name.compareTo(className) == 0)
            {
                type = typeof(Character).getClass();
            }
            else
            {
                throw new System.Exception("could not figure out type: " + className);
            }
            return type;
        }

        public MethodParameter(Type type, int index)
        {
            _type = GetTypeValue(type);
            _parameter = "$" + index;
            _value = null;
        }

        private static Class GetTypeValue(Type type)
        {
            Class objType;
            if (typeof(Long) == type || typeof(long) == type)
            {
                objType = type.getClass();
            }
            else if (typeof(java.Byte) == type || typeof(byte) == type)
            {
                objType = type.getClass();
            }
            else if (typeof(Short) == type || typeof(short) == type)
            {
                objType = type.getClass();
            }
            else if (typeof(Integer) == type || typeof(int) == type)
            {
                objType = type.getClass();
            }
            else if (typeof(Float) == type || typeof(float) == type)
            {
                objType = type.getClass();
            }
            else if (typeof(java.Double) == type || typeof(double) == type)
            {
                objType = type.getClass();
            }
            else if (typeof(java.Boolean) == type || typeof(bool) == type)
            {
                objType = type.getClass();
            }
            else if (typeof(Character) == type || typeof(char) == type)
            {
                objType = type.getClass();
            }
            else if (typeof(String) == type)
            {
                objType = type.getClass();
            }
            else
            {
                objType = null;
            }
            return objType;
        }

        //@Override
        public Object ConvertToValue() // throws Exception 
        {
            if (!_hasValue || IsComplex())
            {
                return null;
            }
            else if (_value == null)
            {
                if (typeof(Long).getClass() == _type || typeof(long).getClass() == _type)
                {
                    _value = Long.parseLong(_parameter);
                }
                else if (typeof(java.Byte).getClass() == _type || typeof(byte).getClass() == _type)
                {
                    _value = byte.Parse(_parameter);
                }
                else if (typeof(Short).getClass() == _type || typeof(short).getClass() == _type)
                {
                    _value = Short.parseShort(_parameter);
                }
                else if (typeof(Integer).getClass() == _type || typeof(int).getClass() == _type)
                {
                    _value = Integer.parseInt(_parameter);
                }
                else if (typeof(Float).getClass() == _type || typeof(float).getClass() == _type)
                {
                    _value = float.Parse(_parameter);
                }
                else if (typeof(java.Double).getClass() == _type || typeof(double).getClass() == _type)
                {
                    _value = double.Parse(_parameter);
                }
                else if (typeof(java.Boolean).getClass() == _type || typeof(bool).getClass() == _type)
                {
                    _value = bool.Parse(_parameter);
                }
                else if (typeof(Character).getClass() == _type || typeof(char).getClass() == _type)
                {
                    _value = _parameter.toCharArray()[0];
                }
                else if (typeof(String).getClass() == _type)
                {
                    _value = _parameter;
                }
                else
                {
                    throw new System.Exception("unknown type: " + _type.getName());
                }
            }
            return _value;
        }

        //@Override
        public Class GetParameterType()
        {
            return _type;
        }

        //@Override
        public String GetValue()
        {
            return _parameter;
        }

        //@Override
        public bool IsComplex()
        {
            return _type == null;
        }

        //@Override
        public String ToXML(int argumentNumber)
        {
            StringBuffer buffer = new StringBuffer();
            buffer.append("<Parameter Value=\"");
            if (IsComplex())
            {
                buffer.append("$" + argumentNumber);
                buffer.append("\" Type=\"Complex\"/>");
            }
            else
            {
                buffer.append(_parameter);
                buffer.append("\" Type=\"");
                buffer.append(_type.getName());
                buffer.append("\"/>");
            }
            return buffer.toString();
        }

    }
}
